package com.skywork.controller.advice;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import com.skywork.utils.RSAUtils;

@ControllerAdvice
public class MyRequestBodyAdvice implements RequestBodyAdvice {

	private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

	@Override
	public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
		// TODO Auto-generated method stub
		return body;
	}

	@Override
	public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
		try {
			return new MyHttpInputMessage(inputMessage);
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
		}
		return inputMessage;
	}

	@Override
	public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
		return body;
	}

	class MyHttpInputMessage implements HttpInputMessage {
		private HttpHeaders headers;

		private InputStream body;

		public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
			String requestBody = IOUtils.toString(inputMessage.getBody(), "UTF-8");
			LOGGER.info("Request body:{}", requestBody);
			HttpHeaders headers = inputMessage.getHeaders();
			List<String> token = headers.get("token");
			if (token != null && token.size() > 0 && StringUtils.isNotBlank(token.get(0))) {

			}

			List<String> publicKey = headers.get("public-key");
			if (publicKey != null && publicKey.size() > 0 && StringUtils.isNotBlank(publicKey.get(0))) {
				String reqStr = RSAUtils.decryptByPublicKey(requestBody, publicKey.get(0));
				LOGGER.info("Request Decrypt body:{}", reqStr);
				this.body = IOUtils.toInputStream(reqStr);
			} else {
				this.body = IOUtils.toInputStream(requestBody);
			}
		}

		@Override
		public InputStream getBody() throws IOException {
			return body;
		}

		@Override
		public HttpHeaders getHeaders() {
			return headers;
		}
	}
}
